home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / master / Examples / Printer_Driver / render.c < prev    next >
C/C++ Source or Header  |  1994-02-01  |  7KB  |  238 lines

  1.  
  2. /*
  3.  *  RENDER.C
  4.  *
  5.  *  David Berezowski - March/88.
  6.  *  Modified for DICE - May/91    Matthew Dillon
  7.  *
  8.  *  Copyright (c) 1988    Commodore-Amiga, Inc.
  9.  *  (c)Copyright 1991 Matthew Dillon
  10.  */
  11.  
  12. #include "defs.h"
  13.  
  14. Prototype __geta4 long Render(long, long, long, long);
  15.  
  16. #define NUMSTARTCMD    8    /* # of cmd bytes before binary data */
  17. #define NUMENDCMD    1    /* # of cmd bytes after binary data */
  18. #define NUMTOTALCMD (NUMSTARTCMD + NUMENDCMD)    /* total of above */
  19. #define NUMLFCMD    4    /* # of cmd bytes for linefeed */
  20. #define MAXCOLORBUFS    4    /* max # of color buffers */
  21.  
  22. #define STARTLEN    16
  23. #define PITCH        1
  24. #define CONDENSED    2
  25. #define LMARG        8
  26. #define RMARG        11
  27. #define DIREC        15
  28.  
  29. __geta4 long
  30. Render(ct, x, y, status)
  31. long ct, x, y, status;
  32. {
  33.     static UWORD RowSize, ColorSize, BufSize, TotalBufSize;
  34.     static UWORD dataoffset, dpi_code;
  35.     static UWORD colors[MAXCOLORBUFS];        /* color ptrs */
  36.     static UWORD colorcodes[MAXCOLORBUFS];  /* printer color codes */
  37.     static UWORD NumColorBufs;            /* actually number of color buffers req. */
  38.  
  39.     /*
  40.         00-01   \003P        set pitch (10 or 12 cpi)
  41.         02-02   \022        set condensed fine (on or off)
  42.         03-05   \033W\000        enlarge off
  43.         06-08   \033ln        set left margin to n
  44.         09-11   \033Qn        set right margin to n
  45.         12-12   \015        carriage return
  46.         13-15   \033U1        set uni-directional mode
  47.     */
  48.  
  49.     static UBYTE StartBuf[STARTLEN] =
  50.         "\033P\022\033W\000\033ln\033Qn\015\033U1";
  51.     UBYTE *ptr, *ptrstart, *ptr2, *ptr2start;
  52.     long i, err;
  53.  
  54.     err = PDERR_NOERR;
  55.  
  56.     switch(status) {
  57.     case 0:    /* Master Initialization */
  58.     /*
  59.      *    ct    - pointer to IODRPReq structure.
  60.      *    x    - width of printed picture in pixels.
  61.      *    y    - height of printed picture in pixels.
  62.      */
  63.     RowSize = x * 3;
  64.     ColorSize = RowSize + NUMTOTALCMD;
  65.     if (PD->pd_Preferences.PrintShade == SHADE_COLOR) {
  66.         NumColorBufs = MAXCOLORBUFS;
  67.         colors[0] = ColorSize * 3; /* Black */
  68.         colors[1] = ColorSize * 0; /* Yellow */
  69.         colors[2] = ColorSize * 1; /* Magenta */
  70.         colors[3] = ColorSize * 2; /* Cyan */
  71.         colorcodes[0] = 4; /* Yellow */
  72.         colorcodes[1] = 1; /* Magenta */
  73.         colorcodes[2] = 2; /* Cyan */
  74.         colorcodes[3] = 0; /* Black */
  75.     } else {    /* grey-scale or black&white */
  76.         NumColorBufs = 1;
  77.         colors[0] = ColorSize * 0; /* Black */
  78.         colorcodes[0] = 0; /* Black */
  79.     }
  80.     BufSize = ColorSize * NumColorBufs + NUMLFCMD;
  81.     TotalBufSize = BufSize * 2;
  82.     PD->pd_PrintBuf = AllocMem(TotalBufSize, MEMF_PUBLIC);
  83.     if (PD->pd_PrintBuf == NULL)
  84.         err = PDERR_BUFFERMEMORY;
  85.     else {
  86.         dataoffset = NUMSTARTCMD;
  87.         /*
  88.          *        This printer prints graphics within its
  89.          *        text margins.  This code makes sure the
  90.          *        printer is in 10 cpi and then sets the
  91.          *        left and right margins to their minimum
  92.          *        and maximum values (respectively).    A
  93.          *        carriage return is sent so that the
  94.          *        print head is at the leftmost position
  95.          *        as this printer starts printing from
  96.          *        the print head's position.  The printer
  97.          *        is put into unidirectional mode to
  98.          *        reduce wavy vertical lines.
  99.          */
  100.         StartBuf[PITCH] = 'P'; /* 10 cpi */
  101.         StartBuf[CONDENSED] = '\022'; /* off */
  102.  
  103.         /* left margin of 1 */
  104.         StartBuf[LMARG] = 0;
  105.         /* right margin of 80 or 136 */
  106.         StartBuf[RMARG] = PD->pd_Preferences.
  107.             PaperSize == W_TRACTOR ? 136 : 80;
  108.         /* uni-directional mode */
  109.         StartBuf[DIREC] = '1';
  110.         err = (*(PD->pd_PWrite))(StartBuf, STARTLEN);
  111.     }
  112.     break;
  113.     case 1: /* Scale, Dither and Render */
  114.         /*
  115.          *        ct        - pointer to PrtInfo structure.
  116.          *        x        - 0.
  117.          *        y        - row # (0 to Height - 1).
  118.          */
  119.     Transfer((void *)ct, y, &PD->pd_PrintBuf[dataoffset], colors);
  120.     break;
  121.     case 2: /* Dump Buffer to Printer */
  122.     /*
  123.      *    ct    - 0.
  124.      *    x    - 0.
  125.      *    y    - # of rows sent (1 to NumRows).
  126.      */
  127.     /* white-space strip */
  128.  
  129.     ptrstart = &PD->pd_PrintBuf[dataoffset];
  130.     ptr2start = ptr2 = ptrstart - NUMSTARTCMD;
  131.     x = 0;                /* flag no transfer required yet */
  132.     for (ct=0; ct<NumColorBufs; ct++, ptrstart += ColorSize) {
  133.         i = RowSize;
  134.         ptr = ptrstart + i - 1;
  135.         while (i > 0 && *ptr == 0) {
  136.         i--;
  137.         ptr--;
  138.         }
  139.         if (i != 0) {   /* if data */
  140.         /* convert to # of pixels */
  141.         i = (i + 2) / 3;
  142.         ptr = ptrstart - NUMSTARTCMD;
  143.         *ptr++ = 27;
  144.         *ptr++ = 'r';
  145.         *ptr++ = colorcodes[ct]; /* color */
  146.         *ptr++ = 27;
  147.         *ptr++ = '*';
  148.         *ptr++ = dpi_code;    /* density */
  149.         *ptr++ = i & 0xff;
  150.         *ptr++ = i >> 8;    /* size */
  151.         i *= 3; /* back to # of bytes used */
  152.         *(ptrstart + i) = 13;    /* cr */
  153.         i += NUMTOTALCMD;
  154.                     /* if must transfer data */
  155.         if (x != 0) {
  156.                     /* get src start */
  157.             ptr = ptrstart - NUMSTARTCMD;
  158.                     /* xfer and update dest ptr */
  159.             do {
  160.                 *ptr2++ = *ptr++;
  161.             } while (--i);
  162.         }
  163.         else {        /* no transfer required */
  164.                 /* update dest ptr */
  165.             ptr2 += i;
  166.         }
  167.         }
  168.         /* if compacted or 0 */
  169.         if (i != RowSize + NUMTOTALCMD) {
  170.         /* we need to transfer next time */
  171.         x = 1;
  172.         }
  173.     }
  174.     *ptr2++ = 13;    /* cr */
  175.     *ptr2++ = 27;
  176.     *ptr2++ = 'J';
  177.     *ptr2++ = y;    /* y/180 lf */
  178.     err = (*(PD->pd_PWrite))(ptr2start, ptr2 - ptr2start);
  179.     if (err == PDERR_NOERR) {
  180.         dataoffset = (dataoffset == NUMSTARTCMD ?
  181.         BufSize : 0) + NUMSTARTCMD;
  182.     }
  183.     break;
  184.     case 3:    /* Clear and Init Buffer */
  185.     /*
  186.      *    ct    - 0.
  187.      *    x    - 0.
  188.      *    y    - 0.
  189.      */
  190.     ptr = &PD->pd_PrintBuf[dataoffset];
  191.     i = BufSize - NUMTOTALCMD - NUMLFCMD;
  192.     do {
  193.         *ptr++ = 0;
  194.     } while (--i);
  195.     break;
  196.     case 4: /* Close Down */
  197.     /*
  198.      *    ct    - error code.
  199.      *    x    - io_Special flag from IODRPReq.
  200.      *    y    - 0.
  201.      */
  202.  
  203.     /* if user did not cancel print */
  204.     if (ct != PDERR_CANCEL) {
  205.         /* restore preferences pitch and margins */
  206.         if (PD->pd_Preferences.PrintPitch == ELITE) {
  207.         StartBuf[PITCH] = 'M'; /* 12 cpi */
  208.         } else if (PD->pd_Preferences.PrintPitch == FINE) {
  209.         StartBuf[CONDENSED] = '\017'; /* on */
  210.         }
  211.         StartBuf[LMARG] = PD->pd_Preferences.PrintLeftMargin - 1;
  212.         StartBuf[RMARG] = PD->pd_Preferences.PrintRightMargin;
  213.         StartBuf[DIREC] = '0'; /* bi-directional */
  214.         err = (*(PD->pd_PWrite))(StartBuf, STARTLEN);
  215.     }
  216.     /* wait for both buffers to empty */
  217.     (*(PD->pd_PBothReady))();
  218.     if (PD->pd_PrintBuf != NULL)
  219.         FreeMem(PD->pd_PrintBuf, TotalBufSize);
  220.     break;
  221.     case 5: /* Pre-Master Initialization */
  222.     /*
  223.      *    ct    - 0 or pointer to IODRPReq structure.
  224.      *    x    - io_Special flag from IODRPReq.
  225.      *    y    - 0.
  226.      *
  227.      *    Kludge for weak power supplies.
  228.      *    FANFOLD - use all 24 pins (default).
  229.      *    SINGLE    - use only 16 pins.
  230.      */
  231.     PED->ped_NumRows = ((PD->pd_Preferences.PaperType == SINGLE) ? 16 : 24);
  232.     dpi_code = SetDensity(x & SPECIAL_DENSITYMASK);
  233.     break;
  234.     }
  235.     return(err);
  236. }
  237.  
  238.